﻿using System;
using System.Transactions;

namespace MusicManager.BL
{
    public static class TransUtil
    {

        //private static object DoInTransactionInternal(Delegate d, params object[] args) {
        //	using (TransactionScope txScope = new TransactionScope()) {
        //		try {
        //			object result = d.DynamicInvoke(args);
        //			txScope.Complete();
        //			return result;
        //		}
        //		catch (TargetInvocationException targetEx) {
        //			Exception innerEx = targetEx.InnerException;
        //			if (innerEx is ApplicationException)
        //				txScope.Complete();
        //			throw innerEx;
        //		}
        //	}
        //}

        public static void DoInTransaction(Action action)
        {
            using (TransactionScope txScope = new TransactionScope())
            {
                try
                {
                    action();
                    txScope.Complete();
                }
                catch (ApplicationException)
                {
                    txScope.Complete();
                    throw;
                }
            }
        }

        public static void DoInTransaction<T1>(Action<T1> action, T1 a1)
        {
            using (TransactionScope txScope = new TransactionScope())
            {
                try
                {
                    action(a1);
                    txScope.Complete();
                }
                catch (ApplicationException)
                {
                    txScope.Complete();
                    throw;
                }
            }
        }

        public static void DoInTransaction<T1, T2>(Action<T1, T2> action, T1 a1, T2 a2)
        {
            using (TransactionScope txScope = new TransactionScope())
            {
                try
                {
                    action(a1, a2);
                    txScope.Complete();
                }
                catch (ApplicationException ex)
                {
                    txScope.Complete();
                    throw;
                }
            }
        }

        public static void DoInTransaction<T1, T2, T3>(Action<T1, T2, T3> action, T1 a1, T2 a2, T3 a3)
        {
            using (TransactionScope txScope = new TransactionScope())
            {
                try
                {
                    action(a1, a2, a3);
                    txScope.Complete();
                }
                catch (ApplicationException ex)
                {
                    txScope.Complete();
                    throw ex;
                }
            }
        }

        public static TResult DoInTransaction<TResult>(Func<TResult> func)
        {
            using (TransactionScope txScope = new TransactionScope())
            {
                try
                {
                    TResult result = func();
                    txScope.Complete();
                    return result;
                }
                catch (ApplicationException ex)
                {
                    txScope.Complete();
                    throw ex;
                }
            }
        }

        public static TResult DoInTransaction<T1, TResult>(Func<T1, TResult> func, T1 a1)
        {
            using (TransactionScope txScope = new TransactionScope())
            {
                try
                {
                    TResult result = func(a1);
                    txScope.Complete();
                    return result;
                }
                catch (ApplicationException ex)
                {
                    txScope.Complete();
                    throw ex;
                }
            }
        }

        public static TResult DoInTransaction<T1, T2, TResult>(Func<T1, T2, TResult> func, T1 a1, T2 a2)
        {
            using (TransactionScope txScope = new TransactionScope())
            {
                try
                {
                    TResult result = func(a1, a2);
                    txScope.Complete();
                    return result;
                }
                catch (ApplicationException ex)
                {
                    txScope.Complete();
                    throw ex;
                }
            }
        }

        public static TResult DoInTransaction<T1, T2, T3, TResult>(Func<T1, T2, T3, TResult> func, T1 a1, T2 a2, T3 a3)
        {
            using (TransactionScope txScope = new TransactionScope())
            {
                try
                {
                    TResult result = func(a1, a2, a3);
                    txScope.Complete();
                    return result;
                }
                catch (ApplicationException ex)
                {
                    txScope.Complete();
                    throw ex;
                }
            }
        }
    }
}
